import ApiV1WxMessageSave_post from "@/api/ApiV1WxMessageSave_post";
import type { IRawMsg } from "@/chatlog_types/IRawMsg";
import { IRawMsgContent_Image } from "@/chatlog_types/IRawMsgContents";
import { MsgTypeEnum } from "@/chatlog_types/MsgTypeEnum";
import { call_native } from "@/utils/call_native";
import { oss_helper } from "@/utils/oss";
import dayjs from "dayjs";
import type { ITask } from "../tasks";
import { TaskType } from "../tasks/TaskType";
import { ghost_messages_forage, job_key } from "./GhostChatMgr";

export function create_msg_commit_job(raw: IRawMsg, src_only: boolean = false): ITask<TaskType.Message, IRawMsg> {

  const title = raw.type === MsgTypeEnum.Image && src_only ? "尝试提交图片消息的大图或原图" : '提交消息'
  const desc = raw.type === MsgTypeEnum.Image && src_only ?
    `对方: ${raw.talker} ` +
    `名称: ${raw.talkerName} ` +
    `时间：${dayjs(raw.time).format('YYYY-MM-DD HH:mm:ss')}` +
    `[当图片从未被打开时, 该任务将失败]`
    :
    `对方: ${raw.talker} ` +
    `名称: ${raw.talkerName} ` +
    `时间：${dayjs(raw.time).format('YYYY-MM-DD HH:mm:ss')}` +
    `内容：${raw.content?.substring(0, 20)}`
  const job = {
    id: `msg_${raw.account}_${raw.talker}_${raw.seq}`,
    title: title,
    desc: desc,
    data: raw,
    type: TaskType.Message as const,
    run: async () => {
      const key = job_key(raw);
      let upload_status: boolean | 'thumb' = true;
      if (raw.type === MsgTypeEnum.Image) {
        const contents = raw.contents as IRawMsgContent_Image;
        if (!contents.img_url && raw.account) {
          try {
            // 上传大图
            const r = await upload_imgs(contents, raw.account, true)
            contents.img_url = r.url;
            upload_status = true;
          } catch (e) {
            // 仅要求大图，但大图不存在时，直接视为任务失败
            if (src_only) throw e;
          }

          // 仅要求大图，说明本地缩略图其实已经成功过了。
          if (!src_only) {
            try {
              // 上传缩略图
              const r = await upload_imgs(contents, raw.account, false)
              if (!contents.img_url) {
                // 当缩略图存在，大图不存在，触发提交，但下次检测是否需要是否提交信息时，仍提交信息
                contents.img_url = r.url;
                upload_status = 'thumb';
              }
            } catch (e) {
              // 连缩略图都没有，绝对就是失败的
              throw e;
            }
          }
        }
      }
      /*
      step0. 查看"本地数据"是否"不存在或有差异"
      step1. 提交数据至服务端
      step2. 完成提交，记录在"本地数据"
      */
      return ApiV1WxMessageSave_post.call({
        ...raw,
        time: dayjs(raw.time).format('YYYY-MM-DD HH:mm:ss'),
      }).then(() => {
        return ghost_messages_forage.setItem(key, upload_status);
      });
    }
  };
  return job;
}

async function upload_imgs(contents: IRawMsgContent_Image, account: string, is_thumb: boolean) {
  if (!contents.path) throw new Error(`path got ${contents.path}`)
  const data_dir = await call_native("GetDataDir").then(r => r.data);
  const img_key = await call_native("GetImgKey").then(r => r.data);

  const file_path = (`${data_dir}/${contents.path}${is_thumb ? '_t' : ''}.dat`).replace(/\\/g, '/')
  const b64_img = await call_native("DecryptImage", img_key, file_path).then(r => r.data)

  const blob = base64_to_blob(b64_img.data);
  const oss_path = `${contents.path!.replace(/\\/g, '/')}${is_thumb ? '_t' : ''}.${b64_img.ext}`
  const result = await oss_helper.put(account!, oss_path, blob)
  return result
}

function base64_to_blob(base64: string) {
  let arr = base64.split(',');
  let mime = arr[0].match(/:(.*?);/)![1];
  let bytes = window.atob(arr[1])
  let ab = new ArrayBuffer(bytes.length);
  let ia = new Uint8Array(ab);
  for (let i = 0; i < bytes.length; i++) {
    ia[i] = bytes.charCodeAt(i);
  }
  return new Blob([ab], { type: mime })
}